﻿namespace Socket.Core
{
    using System;
    using System.Collections.Generic;
    using System.Net.Sockets;

    internal sealed class BufferManager
    {
        private byte[] buffer;
        private readonly int bufferSize;
        private int currentIndex;
        private Stack<int> freeIndexPool;
        private readonly int numSize;

        public BufferManager(int numsize, int buffersize)
        {
            this.numSize = numsize;
            this.bufferSize = buffersize;
        }

        public void Clear()
        {
            BufferManager manager = this;
            lock (manager)
            {
                this.freeIndexPool.Clear();
                this.buffer = null;
            }
        }

        internal void FreeBuffer(SocketAsyncEventArgs args)
        {
            this.freeIndexPool.Push(args.Offset);
            args.SetBuffer(null, 0, 0);
        }

        public void Inint()
        {
            this.buffer = new byte[this.numSize];
            this.freeIndexPool = new Stack<int>(this.numSize / this.bufferSize);
        }

        internal bool SetBuffer(SocketAsyncEventArgs args)
        {
            if (this.freeIndexPool.Count > 0)
            {
                args.SetBuffer(this.buffer, this.freeIndexPool.Pop(), this.bufferSize);
            }
            else
            {
                if ((this.numSize - this.bufferSize) < this.currentIndex)
                {
                    return false;
                }
                args.SetBuffer(this.buffer, this.currentIndex, this.bufferSize);
                this.currentIndex += this.bufferSize;
            }
            return true;
        }
    }
}

